package com.yyge.util;

import cn.hutool.core.lang.UUID;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.yyge.context.JwtContext;
import com.yyge.context.RedisContext;
import com.yyge.dto.ResultCode;
import com.yyge.entity.AdminUser;
import com.yyge.exception.ApplicationException;
import com.yyge.vo.BeanConverter;
import com.yyge.vo.LoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class TokenUtil {
    @Autowired
    private RedisContext redisContext;

    @Autowired
    private JwtContext jwtContext;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 创建登陆用户的koken
     * @param adminUser
     * @return
     */
    public String createToken(AdminUser adminUser) {
        //验证成功,生成UUID

        //生成UUID
        String uuid = UUID.fastUUID().toString();

        //JWT
        Map map=new HashMap();
        map.put("uuid",uuid);
        String token= JWTUtil.createToken(map,jwtContext.getKey().getBytes(StandardCharsets.UTF_8));


        //根据UUID获取redis中的key,格式:"back:jwt:"+UUID
        String redisKey=redisContext.getJWTKey(uuid);

        //redis中保存LoginVO
        //方案3:MapStruct
        LoginVO vo = BeanConverter.MAPPER.emp2LoginVO(adminUser);


        //设置账户类型
        vo.setAccountType(LoginVO.ACCOUNT_TYPE_ADMIN);

        //令牌过期时间(1小时后)
        vo.setExpiredTime(jwtContext.getExpires() + System.currentTimeMillis());

        //设置令牌
        vo.setToken(token);

        System.out.println("你正在设置redisKey:");
        System.out.println(redisKey);
        System.out.println("你正在设置jwtContext.getExpires():");
        System.out.println(jwtContext.getExpires());
        System.out.println("你正在设置TimeUnit.MILLISECONDS:");
        System.out.println(TimeUnit.MILLISECONDS);

        //保存到redis+jwt
        redisTemplate.opsForValue().set(redisKey,vo,jwtContext.getExpires(), TimeUnit.MILLISECONDS);


    return token;
    }


    /**
     * 通过持票人token获取LoginVO对象
     * @param auth
     * @return
     */
    public LoginVO getLoginVO(String auth){
        System.out.println("===============");
        //去除持票人的前缀
        System.out.println(auth);
         auth=auth.replace("Bearer","").trim();

        //验证Token
//        JWTUtil.parseToken(token);
        if(!(JWTUtil.verify(auth,jwtContext.getKey().getBytes(StandardCharsets.UTF_8)))){
            throw new ApplicationException(ResultCode.TOKEN_INVALID);
        }

        //解析令牌
        JWT jwt=JWTUtil.parseToken(auth);

        //获取令牌的UUID
        String uuid=jwt.getPayload("uuid").toString();

        //根据UUID构建Redis种保存LoginVO的key
        String key=redisContext.getJWTKey(uuid);
        return (LoginVO) redisTemplate.opsForValue().get(key);
    }




    /**
     * 删除Token
     * @return void
     */
   public void removeRedisToken(String auth){

        //去除持票人的前缀
         auth=auth.replace("Bearer","").trim();

        //验证Token
//      JWTUtil.parseToken(token);
        if(!(JWTUtil.verify(auth,jwtContext.getKey().getBytes(StandardCharsets.UTF_8)))){
            throw new ApplicationException(ResultCode.TOKEN_INVALID);
        }

        //解析令牌
        JWT jwt=JWTUtil.parseToken(auth);

        //获取令牌的UUID
        String uuid=jwt.getPayload("uuid").toString();

        //根据UUID构建Redis种保存LoginVO的key
        String key=redisContext.getJWTKey(uuid);
        Boolean delete = redisTemplate.delete(key);
        System.out.println("退出成功了么？"+delete);
   }

}
